package com.pactera.asmp.server.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.pactera.asmp.server.common.constants.Constants;
import com.pactera.asmp.server.common.constants.ResultCode;
import com.pactera.asmp.server.common.exception.CustomException;
import com.pactera.asmp.server.common.logprint.utils.CollectionUtils;
import com.pactera.asmp.server.common.logprint.utils.StringUtils;
import com.pactera.asmp.server.dao.DeviceInfoMapper;
import com.pactera.asmp.server.dao.MasterComputerMapper;
import com.pactera.asmp.server.dao.ProductionLineHistoryMapper;
import com.pactera.asmp.server.dao.ProductionLineMapper;
import com.pactera.asmp.server.dao.ProjectMapper;
import com.pactera.asmp.server.dao.ProjectProductionConfigMapper;
import com.pactera.asmp.server.dao.UserMapper;
import com.pactera.asmp.server.dao.UserProjectMapper;
import com.pactera.asmp.server.entity.ProductionLine;
import com.pactera.asmp.server.entity.ProductionLineExample;
import com.pactera.asmp.server.entity.ProductionLineHistory;
import com.pactera.asmp.server.entity.ProjectDetailVo;
import com.pactera.asmp.server.entity.ProjectInfoSearchDTO;
import com.pactera.asmp.server.entity.ProjectModuleBatchDTO;
import com.pactera.asmp.server.entity.ProjectModuleBindDto;
import com.pactera.asmp.server.entity.ProjectModuleDTO;
import com.pactera.asmp.server.entity.ProjectModuleDTO2;
import com.pactera.asmp.server.entity.ProjectProductionConfig;
import com.pactera.asmp.server.entity.ProjectProductionConfigExample;
import com.pactera.asmp.server.entity.dbc.Message;
import com.pactera.asmp.server.pojo.DeviceInfo;
import com.pactera.asmp.server.pojo.FileParse;
import com.pactera.asmp.server.pojo.MasterComputer;
import com.pactera.asmp.server.pojo.ProjectInfo;
import com.pactera.asmp.server.pojo.ProjectVersionInfo;
import com.pactera.asmp.server.pojo.TProjectDeviceDbc;
import com.pactera.asmp.server.pojo.TProjectMasterComputerDbc;
import com.pactera.asmp.server.pojo.User;
import com.pactera.asmp.server.pojo.UserProject;
import com.pactera.asmp.server.pojo.UserProjectKey;
import com.pactera.asmp.server.utils.AssertUtil;
import com.pactera.asmp.server.utils.ExcelUtils;
import com.pactera.asmp.server.utils.PageDataResult;

import org.apache.http.HttpStatus;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import lombok.extern.slf4j.Slf4j;

/**
 * @ProjectName: asmpserver
 * @Package: com.pactera.asmp.server.service
 * @ClassName: ProjectManagerServiceImpl
 * @Author: lvzhiqiang
 * @Description: 项目管理业务实现类
 * @Date: 2019/8/9 17:46
 * @Version: 1.0
 */
@Service
@Slf4j
public class ProjectManagerServiceImpl implements ProjectManagerService {

    @Resource
    public ProjectMapper mProjectMapper;

    @Autowired
    private IProjectDeviceDbcService projectDeviceDbcService;

    @Autowired
    private IProjectMastercDbcService projectMastercDbcService;

    @Autowired
    private ProjectModuleService projectModuleService;

    @Resource
    private UserProjectMapper userProjectMapper;

    @Autowired
    private IFileParseService fileParseService;

    @Resource
    private UserMapper userMapper;

    @Resource
    private DeviceInfoMapper deviceInfoMapper;

    @Resource
    private MasterComputerMapper masterComputerMapper;

    @Resource
    private UserService userService;

    @Resource
    private IProductionLineService productionLineService;

    @Autowired
    private ProjectProductionConfigMapper projectProductionConfigMapper;

    @Autowired
    private ProductionLineMapper productionLineMapper;

    @Autowired
    private ProductionLineHistoryMapper productionLineHistoryMapper;

    @Autowired
    private RestTemplate restTemplate;

    private static final String HEADER = "项目ID,项目名称,项目描述,创建人,项目状态,创建时间";

    @Override
    public PageDataResult getProjectList(ProjectInfoSearchDTO projectInfoSearchDTO, int page, int limit) {
        projectInfoSearchDTO.setProjectIds(userService.getRelatedProject());
        PageDataResult pageDataResult = new PageDataResult();
        PageHelper.startPage(page, limit);
        List<ProjectInfoSearchDTO> list = mProjectMapper.getProjects(projectInfoSearchDTO);
        PageInfo<ProjectInfoSearchDTO> pageInfo = new PageInfo<>(list);
        pageDataResult.setTotals((int) pageInfo.getTotal());
        pageDataResult.setList(list);
        return pageDataResult;
    }

    @Override
    @Transactional
    public String delProjects(List<Integer> datas) {
        if( mProjectMapper.deleteByPrimaryKeys(datas) > 0){
            productionLineService.deleteProductionLineByProjectIds(datas);
            return ResultCode.SUCCESS.message();
        }
        return ResultCode.FAIL.message();
    }

    @Override
    public String delProject(Integer id) {
        if( mProjectMapper.deleteByPrimaryKey(id) > 0){
            return "删除成功";
        }
        return "删除失败";
    }

    @Override
    public String updateProjectInfo(ProjectInfo projectInfo) {
        if( mProjectMapper.updateByPrimaryKeySelective(projectInfo) > 0){
            return "更新成功";
        }
        return "更新失败";
    }

    @Override
    public List<ProjectInfo> getProjectListByUserId(Integer id) {
        return mProjectMapper.getProjectInfoByUserId(id);
    }

    @Override
    public List<ProjectInfo> getProjectName() {
        return this.mProjectMapper.getProjectName(userService.getRelatedProject());
    }

    @Override
    public List<ProjectVersionInfo> getRecentVersion(String projectName) {
        return mProjectMapper.getRecentVersion(projectName);
    }

    @Override
    public List<ProjectVersionInfo> getAllVersion(String projectName) {
        return mProjectMapper.getAllVersion(projectName);
    }

    @Override
    public String getRecentProjectNameByUserEmail(String email){
        ProjectInfo projectInfo =mProjectMapper.getRecentProjectNameByUserEmail(email);
        String projectName = StringUtils.EMPTY;
        if(projectInfo != null){
            projectName = projectInfo.getProjectName();
        }
        return projectName;
    }

    @Override
    public ProjectInfo selectByName(String name) {
        AssertUtil.hasText(name, "项目名称不允许为空");
        return mProjectMapper.selectByName(name);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int add(MultipartFile[] dbcFiles, List<UserProject> userProjects2, Integer[] deviceIds, Integer[] masterComputerIds,
            List<ProjectModuleDTO2> projectModuleDTOs, HttpServletRequest request) {
        User currUser = (User) SecurityUtils.getSubject().getPrincipal();
        List<UserProject> userProjects = userProjects2.stream().filter(e -> e.getUserId() != null).collect(Collectors.toList());
        if (null == currUser) {
            throw new CustomException(ResultCode.PERMISSION_EXPIRE);
        }

        // 记录可选参数
        log.info("project add userIds: {}, deviceIds: {}, moduleNames: {}", userProjects, deviceIds, JSONObject.toJSONString(projectModuleDTOs) );

        String projectName = request.getParameter("projectName");
        if (StringUtils.isEmpty(projectName)) {
            throw new CustomException(ResultCode.PARAM_IS_BLANK);
        }
        if(!projectName.matches(Constants.REGEXP_FIRST_LAST_NOT_SPACE)) {
            throw new CustomException(ResultCode.PARAM_TYPE_BIND_ERROR);
        }

        // 校验项目名是否已存在
        if (null != mProjectMapper.selectByName(projectName)) {
            throw new CustomException(ResultCode.BUSINESS_PROJECTNAME_EXISTED);
        }

        // 校验传入的userId、deviceId、masterComputerId是否存在
        if(!this.validateProjectModuleArgs(CollectionUtils.isNotEmpty(userProjects) 
                ? userProjects.stream().filter(e->e.getUserId() != null).map(UserProject::getUserId).distinct().collect(Collectors.toList()) : null, deviceIds, masterComputerIds)) {
            throw new CustomException(ResultCode.DATA_IS_WRONG);
        }
        ProjectInfo projectInfo = new ProjectInfo();
        projectInfo.setProjectName(projectName);
        projectInfo.setProjectDescription(request.getParameter("projectDescription"));
        projectInfo.setProjectStatus(1);
        LocalDateTime date = LocalDateTime.now();
        projectInfo.setCreateTime(date);
        projectInfo.setCompletionTime(date);
//        projectInfo.setUpdateTime(date);
        projectInfo.setCreateUserId(currUser.getId());
//        projectInfo.setUpdateUserId(currUser.getId());
        projectInfo.setMailSender(request.getParameter("mailSender"));
        projectInfo.setMailServer(request.getParameter("mailServer"));
        projectInfo.setMailPort(request.getParameter("mailPort"));
        String password = request.getParameter("mailPassword");
        if(StringUtils.isEmpty(password)){
            projectInfo.setMailPassword("");
        }else{
            String encodedString = Base64.getEncoder().encodeToString(password.getBytes());
            projectInfo.setMailPassword(encodedString);
        }

        mProjectMapper.insert(projectInfo);

        // 项目绑定设备、用户、模块
        this.bindDeviceAndUserAndModule(projectInfo.getId(), userProjects, deviceIds, masterComputerIds, projectModuleDTOs);

        // 文件上传，解析
        this.handleDbcFile(dbcFiles, projectInfo.getId());

        // 配置流水线信息
        this.configProductionLineInfo(request, projectInfo.getId(), currUser.getId(), date);
        return 1;
    }

    /**
     * 项目绑定设备、用户、模块
     * @param projectId
     * @param userProjects
     * @param deviceIds
     * @param masterComputerIds
     * @param projectModuleDTOs
     * @return
     */
    private int bindDeviceAndUserAndModule(Integer projectId, List<UserProject> userProjects, Integer[] deviceIds, Integer[] masterComputerIds, List<ProjectModuleDTO2> projectModuleDTOs) {
        // 项目绑定设备
        if (CollectionUtils.isArrayNotEmpty(deviceIds)) {
            List<TProjectDeviceDbc> projectDeviceDbcs = new ArrayList<>();
            for (Integer deviceId : deviceIds) {
                TProjectDeviceDbc projectDeviceDbc = new TProjectDeviceDbc();
                projectDeviceDbc.setProjectId(projectId);
                projectDeviceDbc.setDeviceId(deviceId);
                projectDeviceDbcs.add(projectDeviceDbc);
            }
            projectDeviceDbcService.insert(projectDeviceDbcs);
        }

        // 项目绑定上位机
        if (CollectionUtils.isArrayNotEmpty(masterComputerIds)) {
            List<TProjectMasterComputerDbc> projectMasterComputerDbcs = new ArrayList<>();
            for (Integer masterComputerId : masterComputerIds) {
                TProjectMasterComputerDbc projectMasterComputerDbc = new TProjectMasterComputerDbc();
                projectMasterComputerDbc.setProjectId(projectId);
                projectMasterComputerDbc.setMasterComputerId(masterComputerId);
                projectMasterComputerDbcs.add(projectMasterComputerDbc);
            }
            projectMastercDbcService.insert(projectMasterComputerDbcs);
        }

        // 项目模块绑定
        if (CollectionUtils.isNotEmpty(projectModuleDTOs)) {
            ProjectModuleBatchDTO batch = new ProjectModuleBatchDTO();
            batch.setProjectId(projectId);
            batch.setInsert(projectModuleDTOs);
            projectModuleService.batch(batch);
        }

        // 项目用户绑定
        if (CollectionUtils.isNotEmpty(userProjects)) {
            for (UserProject userProject : userProjects) {
                userProject.setProjectId(projectId);
            }
            userProjectMapper.batchInsert(userProjects);
        }
        return 1;
    }

    @Override
    public ProjectDetailVo detail(Integer projectId) {
        if (null == projectId || 0 == projectId) {
            throw new CustomException(ResultCode.PARAM_IS_BLANK);
        }
        ProjectDetailVo projectDetailVo = new ProjectDetailVo();
        // 项目信息
        ProjectInfo projectInfo = mProjectMapper.selectByPrimaryKey(projectId);
        User cUser = userMapper.selectByPrimaryKey(projectInfo.getCreateUserId());
        User uUser = userMapper.selectByPrimaryKey(projectInfo.getUpdateUserId());
        if(null != cUser) {
            projectInfo.setCreateUserName(cUser.getUsername());
        }
        if(null != uUser) {
            projectInfo.setUpdateUserName(uUser.getUsername());
        }
        projectDetailVo.setProjectInfo(projectInfo);

        // 项目模块
        projectDetailVo.setProjectModules(projectModuleService.selectAvailableByProjectId(projectId).getData());

        // 项目用户
        UserProject record = new UserProject();
        record.setProjectId(projectId);
        List<UserProject> userProjectKeys = userProjectMapper.querySelective(record);
        if (CollectionUtils.isNotEmpty(userProjectKeys)) {
            List<Integer> userIds = new ArrayList<>();
            for (UserProjectKey userProjectKey : userProjectKeys) {
                userIds.add(userProjectKey.getUserId());
            }
            projectDetailVo.setUserProjects(userProjectKeys);
            List<User> users = userMapper.selectByPrimaryKeys(userIds);
            users.stream().forEach(user -> {
                Optional<UserProject> optional = userProjectKeys.stream().filter(x -> x.getUserId().intValue() == user.getId().intValue()).findFirst();
                if(optional.isPresent()) {
                    user.setNeedSendMail(optional.get().getNeedSendMail());
                }
            });
            projectDetailVo.setUsers(users);
        }

        // 获取 dbc
        List<FileParse> dbcFiles = fileParseService.selectByProjectId(projectId);
        dbcFiles.stream().forEach(file -> {
            if(StringUtils.isEmpty(file.getParseContent())){
                Object dbcParse = fileParseService.getDbcParse(file.getCid());
                file.setParseContent(String.valueOf(dbcParse));
            }
            String parseContent = file.getParseContent();
            if(CollectionUtils.isEmpty(file.getMessages()) && StringUtils.isNotEmpty(parseContent)){
                List<Message> messages = JSON.parseArray(parseContent, Message.class);
                file.setMessages(messages);
            }
        });
        projectDetailVo.setDbcFiles(dbcFiles);

        projectDetailVo.setProjectProductionConfig(this.getProductionConfig(projectId));
        return projectDetailVo;
    }

    /**
     *
     * @param dbcFiles 新增的DBC文件 (增量数据)
     * @param dbcDeleteIds 删除的DBC文件(增量数据)
     * @param userProjects 所有绑定的用户(全量数据)
     * @param projectModuleDTOs 所有绑定的模块(全量数据)
     * @param request 包括 项目ID、项目名称、项目描述、项目状态
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int update(MultipartFile[] dbcFiles, Long[] dbcDeleteIds, List<UserProject> userProjects,
            List<ProjectModuleDTO2> projectModuleDTOs, HttpServletRequest request) {
        User currUser = (User) SecurityUtils.getSubject().getPrincipal();
        if (null == currUser) {
            throw new CustomException(ResultCode.PERMISSION_EXPIRE);
        }

        // 校验参数
        String projectIdStr = request.getParameter("projectId");
        String projectName = request.getParameter("projectName");
        String projectStatus = request.getParameter("projectStatus");
        String projectDescription = request.getParameter("projectDescription");
        String mailSender = request.getParameter("mailSender");
        String mailServer = request.getParameter("mailServer");
        String mailPort = request.getParameter("mailPort");
        String mailPassword = request.getParameter("mailPassword");
        if (StringUtils.isEmpty(projectIdStr) || StringUtils.isEmpty(projectName)) {
            throw new CustomException(ResultCode.PARAM_IS_BLANK);
        }

        if(!org.springframework.util.StringUtils.isEmpty(projectName)) {
            if(!projectName.matches(Constants.REGEXP_FIRST_LAST_NOT_SPACE)) {
                throw new CustomException(ResultCode.PARAM_TYPE_BIND_ERROR);
            }
            // 校验项目名是否已存在
            if(null != mProjectMapper.selectByIdAndName(Integer.valueOf(projectIdStr),projectName)) {
                throw new CustomException(ResultCode.BUSINESS_PROJECTNAME_EXISTED);
            }
        }

        // 校验传入的userId是否存在
        if(!this.validateProjectModuleArgs(CollectionUtils.isNotEmpty(userProjects)
                ? userProjects.stream().map(UserProject::getUserId).distinct().collect(Collectors.toList()) : null, null, null)) {
            throw new CustomException(ResultCode.DATA_IS_WRONG);
        }
        // 更新项目
        ProjectInfo projectInfo = new ProjectInfo();
        projectInfo.setId(Integer.valueOf(projectIdStr));
        projectInfo.setProjectName(projectName);
        projectInfo.setProjectDescription(projectDescription);
        projectInfo.setUpdateUserId(currUser.getId());
        projectInfo.setUpdateTime(LocalDateTime.now());
        projectInfo.setMailSender(mailSender);
        projectInfo.setMailServer(mailServer);
        projectInfo.setMailPort(mailPort);
        if(null == mailPassword){
            projectInfo.setMailPassword("");
        }else{
            String encodedString = Base64.getEncoder().encodeToString(mailPassword.getBytes());
            projectInfo.setMailPassword(encodedString);
        }

        ProjectDetailVo projectDetailVo = this.detail(projectInfo.getId());
        // 检测项目状态
        if(!StringUtils.isEmpty(projectStatus)){
            projectInfo.setProjectStatus(Integer.valueOf(projectStatus));
            if(!this.checkProjectStatus(projectDetailVo.getProjectInfo().getProjectStatus(),projectInfo.getProjectStatus())){
                log.info("项目状态异常----项目ID:{},修改状态为:{},原始状态:{}",projectIdStr,projectStatus,projectDetailVo.getProjectInfo());
                throw new CustomException(ResultCode.BUSINESS_PROJECT_STATUS_ERR);
            }
        }
        if(!StringUtils.isEmpty(projectName) || !StringUtils.isEmpty(projectDescription) || !StringUtils.isEmpty(projectStatus)) {
            int i = mProjectMapper.updateByStatus(projectInfo, projectDetailVo.getProjectInfo().getProjectStatus());
            if (i < 0) {
                throw new CustomException(ResultCode.BUSINESS_PROJECT_UPDATE_ERR);
            }
        }

        // 整理项目模块
        List<ProjectModuleDTO2> projectModules = null;
        if (CollectionUtils.isNotEmpty(projectModuleDTOs)) {
            projectModules = this.handleProjectModule(projectModuleDTOs, projectDetailVo.getProjectModules());
        }

        // 整理项目用户绑定
        if (CollectionUtils.isNotEmpty(userProjects) && CollectionUtils.isNotEmpty(projectDetailVo.getUserProjects())) {
            userProjectMapper.deleteByPrimaryKeys(projectDetailVo.getUserProjects().stream().map(UserProject::getUserId).distinct().collect(Collectors.toList()), projectInfo.getId());
        }

        this.bindDeviceAndUserAndModule(
                projectInfo.getId(),
                userProjects,
                null,
                null,
                null != projectModules ? projectModules : null);

        // 文件上传，异步解析，新增场景
        this.handleDbcFile(dbcFiles, projectInfo.getId());
        // 配置流水线信息
        this.configProductionLineInfo(request, projectInfo.getId(), currUser.getId(), LocalDateTime.now());
        // 文件删除场景
        if (CollectionUtils.isArrayNotEmpty(dbcDeleteIds)) {
            fileParseService.deleteByPrimaryKeys(Arrays.asList(dbcDeleteIds));
        }

        return 1;
    }

    private boolean checkProjectStatus(Integer dbProjectStatus, Integer newProjectStatus) {
        // 项目状态（0：Closed；1： Open; 2：Pendding; 3： Invalid）
        if(dbProjectStatus == null || newProjectStatus == null) return false;
        if(dbProjectStatus.equals(newProjectStatus)) return true;


        if(dbProjectStatus.intValue() == 1
                && (newProjectStatus== 2 || newProjectStatus== 3 || newProjectStatus==0)) return true;

        if(dbProjectStatus.intValue() == 2
                && (newProjectStatus== 1 || newProjectStatus== 3)) return true;

        if(dbProjectStatus.intValue() == 3 && newProjectStatus== 1) return true;

        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateProjectModule(ProjectModuleBindDto projectModuleBindDto) {
        // 整理项目模块
        List<ProjectModuleDTO2> projectModules = this.handleProjectModule(projectModuleBindDto.getProjectModuleDTOs(),
                projectModuleService.selectAvailableByProjectId(projectModuleBindDto.getProjectId()).getData());
        this.bindDeviceAndUserAndModule(projectModuleBindDto.getProjectId(),
                null, null, null,
                projectModules);
        return 1;
    }

    @Override
    public List<ProjectInfo> getProjectUnbindByDeviceId(Integer deviceId) {
        AssertUtil.notNull(deviceId, "设备ID不允许为空");
        return mProjectMapper.getProjectUnbindByDeviceId(deviceId);
    }

    /**
     * 更新时，对比找出新增和删除的项目模块数据进行操作
     * @param newProjectModuleDTOs
     * @param projectModuleDTOs
     * @return
     */
    private List<ProjectModuleDTO2> handleProjectModule(List<ProjectModuleDTO2> newProjectModuleDTOs, List<ProjectModuleDTO> projectModuleDTOs) {
        // 整理项目模块绑定
        if (CollectionUtils.isEmpty(projectModuleDTOs)) {
            return newProjectModuleDTOs;
        }
        if(CollectionUtils.isEmpty(newProjectModuleDTOs)) {
            projectModuleService.delete(projectModuleDTOs.stream().map(ProjectModuleDTO::getId).distinct().collect(Collectors.toList()));
        }
        // 删除
        List<Integer> delIds = projectModuleDTOs.stream().filter(x -> {
            return newProjectModuleDTOs.stream().noneMatch(y -> StringUtils.equals(x.getName(), y.getName()));
        }).map(ProjectModuleDTO::getId).distinct().collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(delIds)) {
            projectModuleService.delete(delIds);
        }
        // 更新
        newProjectModuleDTOs.stream().filter(x -> {
            return projectModuleDTOs.stream().anyMatch(y -> StringUtils.equals(x.getName(), y.getName()));
        }).forEach(newProjectModuleDTO ->{
            ProjectModuleDTO projectModuleDTO = new ProjectModuleDTO();
            BeanUtils.copyProperties(newProjectModuleDTO, projectModuleDTO);
            projectModuleService.update(projectModuleDTO);
        });
        // 新增
        return newProjectModuleDTOs.stream().filter(x -> {
            return projectModuleDTOs.stream().noneMatch(y -> StringUtils.equals(x.getName(), y.getName()));
        }).collect(Collectors.toList());
    }

//    /**
//     * 更新时，对比找出新增和删除的项目用户数据进行操作
//     * @param userIds
//     * @param users
//     * @param projectId
//     * @return
//     */
//    private List<Integer> handleProjectUser(List<Integer> userIds, List<User> users, Integer projectId) {
//        // 整理项目用户绑定
//        List<Integer> userIdList = new ArrayList<>();
//        if (CollectionUtils.isNotEmpty(users)) {
//            for (User user : users) {
//                userIdList.add(user.getId());
//            }
//        }
//
//        if (CollectionUtils.isEmpty(userIds)) {
//            userIds = new ArrayList<>();
//        }
//        List<Integer> newUserIds = new ArrayList();
//        for (Integer userId : userIds) {
//            if (!userIdList.contains(userId)) {
//                newUserIds.add(userId);
//            } else {
//                userIdList.remove(userId);
//            }
//        }
//        if (CollectionUtils.isNotEmpty(userIdList)) {
//            userProjectMapper.deleteByPrimaryKeys(userIdList, projectId);
//        }
//        return newUserIds;
//    }

    private void handleDbcFile(MultipartFile[] dbcFiles, Integer projectId) {
        // 文件上传，解析
        if (CollectionUtils.isArrayNotEmpty(dbcFiles)) {
            for (MultipartFile dbcFile : dbcFiles) {
                FileParse fileParse = fileParseService.uploadAndInsert(dbcFile, projectId);
                try {
                    fileParseService.parseFileAndUpdate(dbcFile.getInputStream(), fileParse.getCid());
                } catch (Exception e) {
                    throw new CustomException(ResultCode.UPLOAD_ERROR);
                }
            }
        }
    }

    private boolean validateProjectModuleArgs(List<Integer> userIds, Integer[] deviceIds, Integer[] masterComputerIds) {
        if(CollectionUtils.isNotEmpty(userIds)) {
            List<Integer> userIdList = Lists.newArrayList(userIds).stream().distinct().collect(Collectors.toList());
            List<User> users = userMapper.selectByPrimaryKeys(userIdList);
            if(users == null) {
                return false;
            }
            if(users.size() != userIdList.size()) {
                return false;
            }
        }
        if(deviceIds != null && deviceIds.length > 0) {
            List<Integer> deviceIdList = Lists.newArrayList(deviceIds).stream().distinct().collect(Collectors.toList());
            List<DeviceInfo> deviceInfos = deviceInfoMapper.selectByPrimaryKeys(deviceIdList, null);
            if(deviceInfos == null) {
                return false;
            }
            if(deviceInfos.size() != deviceIdList.size()) {
                return false;
            }
        }
        if(masterComputerIds != null && masterComputerIds.length > 0) {
            List<Integer> masterComputerIdList = Lists.newArrayList(masterComputerIds).stream().distinct().collect(Collectors.toList());
            List<MasterComputer> masterComputers = masterComputerMapper.findMasterComputerByIds(masterComputerIdList);
            if(masterComputers == null) {
                return false;
            }
            if(masterComputers.size() != masterComputerIdList.size()) {
                return false;
            }
        }
        return true;
    }

    /**
     * 删除项目关联的用户
     *
     */
    @Override
    public int delProjectUser(Integer[] userIds, Integer projectId) {
        // 校验传入的userId是否存在
        if(!this.validateProjectModuleArgs(Lists.newArrayList(userIds), null, null)) {
            throw new CustomException(ResultCode.DATA_IS_WRONG);
        }
        return userProjectMapper.deleteByPrimaryKeys(Lists.newArrayList(userIds), projectId);
    }

    /**
     * 导出项目信息
     */
    @Override
    public void export(ProjectInfoSearchDTO projectInfoSearchDTO, HttpServletResponse response) {
        try {
            projectInfoSearchDTO.setProjectIds(userService.getRelatedProject());
            List<ProjectInfoSearchDTO> list = mProjectMapper.getProjects(projectInfoSearchDTO);
            List<List<String>> dataList = Lists.newArrayList();
            if(CollectionUtils.isNotEmpty(list)) {
                dataList.addAll(list.stream().map(projectInfo -> {
                    List<String> data = new ArrayList<>();
                    data.add(String.valueOf(projectInfo.getId()));
                    data.add(projectInfo.getProjectName());
                    data.add(projectInfo.getProjectDescription());
                    data.add(projectInfo.getCreateUserName());
                    switch (projectInfo.getProjectStatus()) {
                        // 0：Closed；
                        case 0:
                            data.add("Closed");
                            break;
                        // 1： Open
                        case 1:
                            data.add("Open");
                            break;
                        // 2：Pendding
                        case 2:
                            data.add("Pendding");
                            break;
                        //3： Invalid
                        case 3:
                            data.add("Invalid");
                            break;
                        default:
                            data.add("");
                            break;
                    }
                    data.add(projectInfo.getCreateTime());
                    return data;
                }).collect(Collectors.toList()));
            }
            ExcelUtils.writeExcel(response, Lists.newArrayList(HEADER.split(",")), dataList, "项目");
        }catch(Exception e) {
            ExcelUtils.writeExcel(response, Lists.newArrayList(HEADER.split(",")), Lists.newArrayList(), "项目");
        }
    }

    /**
     * 配置流水线信息
     *
     * @param request
     * @param projectId
     * @param userId
     * @param localDateTime
     */
    private void configProductionLineInfo(HttpServletRequest request, Integer projectId, Integer userId, LocalDateTime localDateTime) {
        // 流水线工具
        String productionTool = request.getParameter("productionTool");
        // 流水线url
        String productionUrl = request.getParameter("productionUrl");
        // 流水线账号
        String productionUsername = request.getParameter("productionUsername");
        // 流水线密码
        String productionPassword = request.getParameter("productionPassword");
        if(StringUtils.isEmpty(productionTool) || StringUtils.isEmpty(productionUrl)
                || StringUtils.isEmpty(productionUsername) || StringUtils.isEmpty(productionPassword)) {
            return;
        }

        // 校验输入的流水线信息
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setBasicAuth(productionUsername, productionPassword);
        HttpEntity<String> httpEntity = new HttpEntity<>(httpHeaders);
        try {
            ResponseEntity<String> response = restTemplate.exchange(productionUrl, HttpMethod.GET, httpEntity, String.class);
            if(HttpStatus.SC_OK != response.getStatusCodeValue()) {
                throw new CustomException(ResultCode.BUSINESS_PROJECT_PRODUCTION_LINE_ERROR);
            }
            String msg = response.getBody();
            JSONObject jsonObject = JSONObject.parseObject(msg);
            List<Map<String, Object>> jobs = (List<Map<String, Object>>)jsonObject.get("jobs");
            if(CollectionUtils.isEmpty(jobs)) {
                throw new CustomException(ResultCode.BUSINESS_PROJECT_PRODUCTION_LINE_ERROR);
            }
        }catch (Exception ex) {
            log.error("production error. {}", ex.getMessage());
            throw new CustomException(ResultCode.BUSINESS_PROJECT_PRODUCTION_LINE_ERROR);
        }
        ProjectProductionConfigExample example = new ProjectProductionConfigExample();
        example.createCriteria().andProjectIdEqualTo(projectId);
        List<ProjectProductionConfig> projectProductionConfigs = projectProductionConfigMapper.selectByExample(example);
        if(CollectionUtils.isEmpty(projectProductionConfigs)) {
            ProjectProductionConfig projectProductionConfig = new ProjectProductionConfig();
            projectProductionConfig.setProjectId(projectId);
            projectProductionConfig.setProductionTool(productionTool);
            projectProductionConfig.setProductionUrl(productionUrl);
            projectProductionConfig.setProductionUsername(productionUsername);
            projectProductionConfig.setProductionPassword(productionPassword);
            projectProductionConfig.setCreateUid(userId);
            projectProductionConfig.setCreateTime(localDateTime);
            projectProductionConfigMapper.insertSelective(projectProductionConfig);
        }else {
            ProjectProductionConfig projectProductionConfig = projectProductionConfigs.get(0);
            // 流水线配置发生变更时，删除项目已有的流水线
            if(!StringUtils.equals(projectProductionConfig.getProductionUrl(), productionUrl)) {
                ProductionLineExample productionLineExample = new ProductionLineExample();
                productionLineExample.createCriteria().andProjectIdEqualTo(projectId);
                List<ProductionLine> productionLines = productionLineMapper.selectByExample(productionLineExample);
                if(CollectionUtils.isNotEmpty(productionLines)) {
                    for(ProductionLine productionLine: productionLines) {
                        ProductionLineHistory productionLineHistory =new ProductionLineHistory();
                        BeanUtils.copyProperties(productionLine, productionLineHistory);
                        productionLineHistory.setId(null);
                        productionLineHistory.setProductionLineId(productionLine.getId());
                        productionLineHistoryMapper.insertSelective(productionLineHistory);
                    }
                    productionLineMapper.deleteByExample(productionLineExample);
                }
            }
            projectProductionConfig.setProductionTool(productionTool);
            projectProductionConfig.setProductionUrl(productionUrl);
            projectProductionConfig.setProductionUsername(productionUsername);
            projectProductionConfig.setProductionPassword(productionPassword);
            projectProductionConfig.setUpdateUid(userId);
            projectProductionConfig.setUpdateTime(localDateTime);
            projectProductionConfigMapper.updateByPrimaryKeySelective(projectProductionConfig);
        }
    }

    /**
     * 获取流水线配置信息
     *
     * @param *localDateTime
     * @return
     */
    @Override
    public ProjectProductionConfig getProductionConfig(Integer projectId) {
        if (null == projectId || 0 == projectId) {
            throw new CustomException(ResultCode.PARAM_IS_BLANK);
        }
        ProjectProductionConfigExample example = new ProjectProductionConfigExample();
        example.createCriteria().andProjectIdEqualTo(projectId);
        List<ProjectProductionConfig> projectProductionConfigs = projectProductionConfigMapper.selectByExample(example);
        if(CollectionUtils.isEmpty(projectProductionConfigs)) {
            return null;
        }
        return projectProductionConfigs.get(0);
    }

}
